1 /** 2 The following examples come from 3 $(LINK http://zetcode.com/db/sqlite/constraints/). 4 Even though it is a SQLite tutorial the point is to show how to use this package 5 which does not have to be just SQLite. 6 */ 7 module test.examples_notnull; 8 9 version(D_Ddoc) 10 { 11 /// 12 class BlankClassSoDocsWillBeGenerated { } 13 } 14 15 /** 16 This example is for the NOT NULL constraint. The table 17 in SQL can be created by 18 $(D $(D $(D sql 19 CREATE TABLE People 20 ( 21 Id INTEGER NOT NULL PRIMARY KEY, 22 LastName TEXT NOT NULL, 23 FirstName TEXT NOT NULL, 24 City TEXT 25 ); 26 27 ))) 28 29 I will create the singular class (or row class). The singular class 30 should include a dup method and the mixin KeyedItem. The columns in the 31 singular class should have a private member with getters and setters. No 32 plural class (or table class) is needed for this example. 33 34 In making this package, I have made the assumption that the private member 35 begins with an underscore and the getters and setters have the same name 36 as the private member except no beginning underscore. 37 The keyed item must also have some Unique constraint and will not compile 38 without one. 39 40 The setter method provided in KeyedItem should be used in your setters. This 41 will check if you are setting it to the same value, if the value causes any 42 check constraints to be violated and if everything goes well notifies the 43 plural class (or table) of the changes. 44 */ 45 unittest 46 { 47 import db_constraints; 48 49 // this is what I call the singular class 50 // you can also think of it as a row in the database. 51 // it contains all of the columns and tells us which 52 // columns have which constraints 53 class Person 54 { 55 private int _Id; 56 // marking Id with not null and primary key 57 @NotNull @PrimaryKeyColumn 58 @property int Id() 59 { 60 return _Id; 61 } 62 @property void Id(int value) 63 { 64 setter(_Id, value); 65 } 66 67 private string _LastName; 68 // marking LastName with not null 69 @NotNull 70 @property string LastName() 71 { 72 return _LastName; 73 } 74 @property void LastName(string value) 75 { 76 setter(_LastName, value); 77 } 78 79 private string _FirstName; 80 // marking FirstName with not null 81 @NotNull 82 @property string FirstName() 83 { 84 return _FirstName; 85 } 86 @property void FirstName(string value) 87 { 88 setter(_FirstName, value); 89 } 90 91 private string _City; 92 // not marking City with anything 93 @property string City() 94 { 95 return _City; 96 } 97 @property void City(string value) 98 { 99 setter(_City, value); 100 } 101 102 this(int Id_, string LastName_, string FirstName_, string City_) 103 { 104 this._Id = Id_; 105 this._LastName = LastName_; 106 this._FirstName = FirstName_; 107 this._City = City_; 108 // do not forget to initialize the keyed item! 109 initializeKeyedItem(); 110 } 111 112 // the keyed item mixin will create all the necessary 113 // checks for you 114 mixin KeyedItem!(); 115 } 116 117 118 import std.exception : assertNotThrown, assertThrown; 119 // I will make a single row with values for all columns 120 // this does not throw an exception because none of the 121 // check constraints are violated. 122 assertNotThrown!CheckConstraintException(new Person(1, "Hanks", 123 "Robert", "New York")); 124 125 // the next Person throws a check constraint exception 126 // since we try to make a Person that has a null LastName 127 assertThrown!CheckConstraintException(new Person(2, null, 128 "Marianne", "Chicago")); 129 }